package com.example.demo.utils.encrypt;


import com.example.demo.utils.StringUtil;

import java.util.*;
import java.util.regex.Pattern;

/**
 * 签名生产和校验类
 */
public class SignUtil
{

    /**
     * 签名字符串分隔符
     */
    private static final String SIGNATURE_DECOLLATOR = "|";

    private static final String SIGNATURE_SPECIAL_THREE_FIELD = ">";

    private static final String SIGNATURE_SPECIAL_ELEVEN_LETTER_ = "*";

    /**
     * 默认签名秘钥
     */
    private static String DEFAULT_SIGNATURE_KEY = "LINCOMB$_@(#PAY";

    /**
     * 获取签名字符串
     *
     * @param params -- 签名参数
     * @return
     */
    public static String getSign(Map<String, String> params)
    {
        if (params != null && !params.isEmpty())
        {
            return getSignature(params, DEFAULT_SIGNATURE_KEY);
        }

        return null;
    }

    public static String getSign(Map<String, String> params, String signKey)
    {
        if (params != null && !params.isEmpty())
        {
            return getSignature(params, StringUtil.isEmpty(signKey) ? DEFAULT_SIGNATURE_KEY : signKey);
        }

        return null;
    }

    /**
     * 校验签名
     *
     * @param params
     * @param origSign
     * @return
     */
    public static boolean validSign(Map<String, String> params, String origSign)
    {
        if (!StringUtil.isEmpty(origSign) && params != null && !params.isEmpty())
        {
            String nowSign = getSign(params, DEFAULT_SIGNATURE_KEY);
            if (origSign.trim().equals(nowSign))
            {
                return true;
            }
        }

        return false;
    }

    public static boolean validSign(Map<String, String> params, String origSign, String signKey)
    {
        if (!StringUtil.isEmpty(origSign) && params != null && !params.isEmpty())
        {
            String nowSign = getSign(params, signKey);
            if (origSign.trim().equals(nowSign))
            {
                return true;
            }
        }

        return false;
    }

    /**
     * 校验签名
     *
     * @param origSign
     * @return
     */
    public static boolean validSign(String newSign, String origSign)
    {
        if (!StringUtil.isEmpty(newSign) && !StringUtil.isEmpty(origSign))
        {
            if (origSign.trim().equals(newSign))
            {
                return true;
            }
        }

        return false;
    }

    /**
     * 生成签名
     *
     * @param params
     * @return
     */
    private static String getSignature(Map<String, String> params, String signKey)
    {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys, new Comparator<String>()
        {
            public int compare(String str1, String str2)
            {
                return str1.compareTo(str2);
            }
        });

        StringBuffer signStr = new StringBuffer();
        String value = null;
        int count = 1;
        for (String key : keys)
        {
            value = params.get(key);
            if (!StringUtil.isEmpty(value) && !isChinese(value))
            {
                if (count % 3 == 0)
                {
                    value += SIGNATURE_SPECIAL_THREE_FIELD;
                }
                signStr.append(value.trim()).append(SIGNATURE_DECOLLATOR);
                count++;
            }
        }

        int len = signStr.length() / 10;
        for (int i = 1; i <= len; i++)
        {
            signStr.insert(i * 10, SIGNATURE_SPECIAL_ELEVEN_LETTER_);
        }
        signStr.append(signKey);
        String sign = MD5Util.MD5Encode(signStr.toString(), null).toUpperCase();
        return sign;
    }

    /**
     * 完整的判断中文汉字和符号
     *
     * @param str
     * @return
     */
    private static boolean isChinese(String str)
    {
        if (!StringUtil.isEmpty(str))
        {
            Pattern pattern = Pattern.compile("[\\u4E00-\\u9FBF]+");
            if (pattern.matcher(str.trim()).find())
            {
                return true;
            } else
            {
                char[] ch = str.toCharArray();
                for (int i = 0; i < ch.length; i++)
                {
                    Character.UnicodeBlock ub = Character.UnicodeBlock.of(ch[i]);
                    if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION)
                    {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    /**
     * 设置签名
     *
     * @param key
     */
    public void setKey(String key)
    {
        SignUtil.DEFAULT_SIGNATURE_KEY = key;
    }
}